package com.ruoyi.patrol.service.impl;

import com.ruoyi.common.constant.PatrolConstans;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.IsEmptyUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.patrol.domain.PtStaff;
import com.ruoyi.patrol.mapper.PtStaffMapper;
import com.ruoyi.patrol.service.IPtStaffService;
import com.ruoyi.patrol.utils.AreaCodeMapUtils;
import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 行政人员Service业务层处理
 *
 * @author lkm
 * @date 2022-11-14
 */
@Service
public class PtStaffServiceImpl implements IPtStaffService {
    private static final Logger log = LoggerFactory.getLogger(PtStaffServiceImpl.class);
    @Autowired
    private PtStaffMapper ptStaffMapper;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private SysUserRoleMapper userRoleMapper;

    @Autowired
    private SysUserMapper userMapper;

    /**
     * 查询行政人员
     *
     * @param id 行政人员ID
     * @return 行政人员
     */
    @Override
    public PtStaff selectPtStaffById(Long id) {
        return ptStaffMapper.selectPtStaffById(id);
    }

    /**
     * 查询行政人员列表
     *
     * @param ptStaff 行政人员
     * @return 行政人员
     */
    @Override
    public List<PtStaff> selectPtStaffList(PtStaff ptStaff) {
        return ptStaffMapper.selectPtStaffList(ptStaff);
    }

    /**
     * 新增行政人员
     *
     * @param ptStaff 行政人员
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertPtStaff(PtStaff ptStaff) {
        ptStaff.setSchoolId(SecurityUtils.getSchoolId());
        ptStaff.setCreateTime(DateUtils.getNowDate());
        ptStaff.setCreateBy(SecurityUtils.getUsername());
        int i = ptStaffMapper.insertPtStaff(ptStaff);

        // 为行政人员添加登录账号
        SysUser user = new SysUser();
        user.setUserName(ptStaff.getStaffPhonenumber());
        user.setNickName(ptStaff.getStaffName());
        user.setPhonenumber(ptStaff.getStaffPhonenumber());
        user.setSex(ptStaff.getStaffSex());
        // fixed elis  取出默认后6位密码改为 XYxc123456!@ 紧急修复先用硬编码 TODO
        user.setPassword(SecurityUtils.encryptPassword("XYxc123456!@"));
        user.setCreateBy(SecurityUtils.getUsername());
        user.setSchoolId(ptStaff.getSchoolId());
        user.setStaffId(ptStaff.getId());
        userService.insertUser(user);
        // 为行政人员添加角色
        SysRole role = roleService.selectRoleByRoleKey("staff");
        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(role.getRoleId());
        userRole.setUserId(user.getUserId());
        userRoleMapper.insertUserRole(userRole);
        return i;
    }

    /**
     * 修改行政人员
     *
     * @param ptStaff 行政人员
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updatePtStaff(PtStaff ptStaff) {
        ptStaff.setUpdateTime(DateUtils.getNowDate());
        ptStaff.setUpdateBy(SecurityUtils.getUsername());
        int i = ptStaffMapper.updatePtStaff(ptStaff);
//        int i1 = userMapper.checkUserNameUnique(ptStaff.getStaffPhonenumber());
//        if (i1>1){
//            throw new CustomException("手机号已存在!");
//        }
        // 更新账号信息
        SysUser user = userService.selectUserByStaffId(ptStaff.getId());
        user.setUserName(ptStaff.getStaffPhonenumber());
        user.setNickName(ptStaff.getStaffName());
        user.setPhonenumber(ptStaff.getStaffPhonenumber());
        user.setSex(ptStaff.getStaffSex());
        // 密码默认为电话号码后6位
        // fixed elis 修复在更新人员信息时会将密码重置问题
//        user.setPassword(SecurityUtils.encryptPassword(ptStaff.getStaffPhonenumber().substring(5)));
        user.setUpdateBy(SecurityUtils.getUsername());
        userService.updateUserMy(user);
        return i;
    }

    /**
     * 批量删除行政人员
     *
     * @param ids 需要删除的行政人员ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deletePtStaffByIds(Long[] ids) {
        int j = userService.deleteUserByStaffIds(ids);
        int i = ptStaffMapper.deletePtStaffByIds(ids);
        return i;
    }

    /**
     * 导入行政用户数据
     *
     * @param staffList       用户数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作用户
     * @return 结果
     */
    @Override
    public String importStaff(List<PtStaff> staffList, Boolean isUpdateSupport, String operName) throws IOException {
        if (StringUtils.isNull(staffList) || staffList.size() == 0) {
            throw new CustomException("导入行政用户数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        //获取地区code map
        Map<String, String> map = AreaCodeMapUtils.getAreaCode();
        //遍历导入的数据集合
        for (int i = 0; i < staffList.size(); i++) {
            PtStaff staff = staffList.get(i);

            boolean is = IsEmptyUtils.isEmpty(staff.getStaffName(), staff.getStaffPost(), staff.getStaffPhonenumber(), staff.getStaffPoliticalExamine(), staff.getStaffPhysicalCondition());
            if (is) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、第 " + (i + 1) + " 条数据必填项不全");
                continue;
            }
            //验证身份证是否匹配
            String sIdCard = staff.getStaffIdcard();
            if (!StringUtils.isEmpty(sIdCard) && !Pattern.matches("^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[\\dXx]$", sIdCard)) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、第 " + (i + 1) + "条数据【身份证格式】错误");
                continue;
            }

            //验证手机号是否匹配
            String phoneNUm = staff.getStaffPhonenumber();
            if (!StringUtils.isEmpty(phoneNUm) && !Pattern.matches("^1[3-9]\\d{9}$", phoneNUm)) {
                failureNum++;
                failureMsg.append("<br/>" + failureNum + "、第 " + (i + 1) + "条数据【手机号格式】错误");
                continue;
            }

            try {
                // 验证是否存在这个用户
                //身份证验证
                PtStaff staffIdcard = ptStaffMapper.checkIdcardUnique(staff);
                //手机号验证
                PtStaff staffPhone = ptStaffMapper.checkPhoneUnique(staff);
                int checkUserNameUnique = userMapper.checkUserNameUnique(staff.getStaffPhonenumber());

                staff.setStaffSex("0".equals(staff.getStaffSex()) || "1".equals(staff.getStaffSex()) ? staff.getStaffSex() : "2");
                staff.setStaffNativePlace(map.get(staff.getStaffNativePlace()) == null ? "" : map.get(staff.getStaffNativePlace()));
                if (checkUserNameUnique > 0) {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append("、第 ").append(i + 1).append("条数据【电话号码】已存在");
                    continue;
                }
                if (staffIdcard != null) {
                    staff.setId(staffIdcard.getId());
                }

                if (staffPhone != null) {
                    staff.setId(staffPhone.getId());
                }

                //不存在(添加用户)
                if (StringUtils.isNull(staffIdcard) && StringUtils.isNull(staffPhone)) {
                    insertPtStaff(staff);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、用户 " + staff.getStaffName() + " 导入成功");
                } else if (isUpdateSupport) {
                    staff.setUpdateBy(operName);
                    this.updatePtStaff(staff);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、用户 " + staff.getStaffName() + " 更新成功");
                } else {
                    failureNum++;
                    if (staffPhone != null) {
                        failureMsg.append("<br/>" + failureNum + "、第 " + (i + 1) + " 条数据【电话号码】已存在");
                    } else {
                        failureMsg.append("<br/>" + failureNum + "、第 " + (i + 1) + " 条数据【身份证号码】已存在");
                    }
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、第 " + (i + 1) + "条数据导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "成功数据：" + successNum + " 条!<br/>" + "失败数据：共 " + failureNum + " 条，失败原因如下：");
            throw new CustomException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }


    /**
     * 删除行政人员信息
     *
     * @param id 行政人员ID
     * @return 结果
     */
    @Override
    public int deletePtStaffById(Long id) {
        return ptStaffMapper.deletePtStaffById(id);
    }

    @Override
    public String checkPhoneUnique(PtStaff ptStaff) {
        if (ptStaff.getId() != null) { // 表明是修改
            PtStaff staff = ptStaffMapper.selectPtStaffById(ptStaff.getId());
            if (staff.getStaffPhonenumber().equals(ptStaff.getStaffPhonenumber())) { // 如果前端传过来的电话和后端的一样，表明没有修改
                return PatrolConstans.UNIQUE;
            }
        }
        SysUser user = userMapper.checkPhoneUnique(ptStaff.getStaffPhonenumber());
        if (ObjectUtils.isEmpty(user)) {
            return PatrolConstans.UNIQUE;
        }
        return PatrolConstans.NOT_UNIQUE;
    }

    @Override
    public String checkIdcardUnique(PtStaff ptStaff) {
        if (StringUtils.isEmpty(ptStaff.getStaffIdcard())) {
            return PatrolConstans.UNIQUE;
        }
        if (ptStaff.getId() != null) { // 如果是修改，需要排除自己的身份证号码
            PtStaff staff = ptStaffMapper.selectPtStaffById(ptStaff.getId());
            if (!StringUtils.isEmpty(staff.getStaffIdcard()) && staff.getStaffIdcard().equals(ptStaff.getStaffIdcard())) { // 如果前端传来的和数据库中查询的自己的身份证号码一样，表明没有进行变动，说明是唯一的
                return PatrolConstans.UNIQUE;
            }
        }
        PtStaff staff = ptStaffMapper.checkIdcardUnique(ptStaff);
        if (ObjectUtils.isEmpty(staff)) {
            return PatrolConstans.UNIQUE;
        }
        return PatrolConstans.NOT_UNIQUE;
    }

    @Override
    public int selectStaffCount(Long schoolId) {
        return ptStaffMapper.selectStaffCount(schoolId);
    }

    @Override
    public boolean isStaffOnSchedule(Long staffId) {
        return ptStaffMapper.isStaffOnSchedule(staffId);
    }
}
